/**
 * @author ens12ilt - ens12ple
 */

package utils;

public class VectorUtils {

	/**
	 * 
	 * @param u first vector
	 * @param v second vector
	 * @return the cosinus value between u and v
	 */
	public static double getCosinus(int[] u, int[] v){
		return scalarDot(u, v)/(norm2(u) * norm2(v));
	}
	
	/**
	 * 
	 * @param u first vector
	 * @param v second vector
	 * @return the sinus value between u and v
	 */
	public static double getSinus(int[] u, int[] v){
		return Math.signum(vectProd(u, v)[2]) * norm2(vectProd(u, v))/(norm2(u) * norm2(v));
	}
	/**
	 * 
	 * @param u first vector
	 * @param v second vector
	 * @return the angle value between u and v
	 */
	public static double getAngle(int[] u, int[] v){
		double cos = getCosinus(u, v);
		double sin = getSinus(u, v);
		if(sin > 0){
			return Math.acos(cos);
		}else{
			return -Math.acos(cos);
		}
	}
	/**
	 * 
	 * @param u first vector
	 * @param v second vector
	 * @return the dot product value between u and v
	 */
	public static double scalarDot(int[] u, int[] v)  throws IllegalArgumentException{
		double scalarDot = 0;
		if(u.length != v.length){
			throw new IllegalArgumentException("u and v size must match");
		}
		for(int i = 0; i < u.length; i++){
			scalarDot += u[i] * v[i];
		}
		return scalarDot;
	}
	
	/**
	 * 
	 * @param u vector
	 * @return the norm of u
	 */
	public static double norm2(int[] u){
		double norm = 0;
		for(int i = 0; i < u.length; i++){
			norm += Math.pow(u[i], 2);
		}
		return Math.sqrt(norm);
	}
	
	/**
	 * 
	 * @param u first vector
	 * @param v second vector
	 * @return vector product value for u and v
	 * @throws IllegalArgumentException
	 */
	public static int[] vectProd(int[] u, int[] v) throws IllegalArgumentException{
		if(u.length != v.length){
			throw new IllegalArgumentException("u and v size must match");
		}
		int[] ret = new int[3];
		if(u.length == 2){
			ret[0] = 0;
			ret[1] = 0;
			ret[2] = u[0]*v[1] - u[1]*v[0];
		}else if(u.length == 3){
			ret[0] = u[1]*v[2] - u[2]*v[1];
			ret[1] = u[2]*v[0] - u[0]*v[2];
			ret[2] = u[0]*v[1] - u[1]*v[0];
		}else{
			return null;
		}
		return ret;
	}
}
